package com.blog.cmrpersonalblog.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.blog.cmrpersonalblog.entity.SysUser;
import com.blog.cmrpersonalblog.entity.SysRole;
import com.blog.cmrpersonalblog.mapper.SysUserMapper;
import com.blog.cmrpersonalblog.service.SysUserService;
import com.blog.cmrpersonalblog.service.SysUserRoleService;
import com.blog.cmrpersonalblog.service.SysRoleService;
import com.blog.cmrpersonalblog.common.PageResult;
import com.blog.cmrpersonalblog.dto.user.request.*;
import com.blog.cmrpersonalblog.dto.user.response.UserResponse;
import com.blog.cmrpersonalblog.utils.PasswordUtils;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 系统用户服务实现类
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

   @Resource
    private SysUserRoleService sysUserRoleService;

   @Resource
    private SysRoleService sysRoleService;

    @Override
    public SysUser getUserByUserName(String userName) {
        return baseMapper.selectUserByUserName(userName);
    }

    @Override
    public SysUser getUserByEmail(String email) {
        return baseMapper.selectUserByEmail(email);
    }

    @Override
    public List<String> getUserPermissions(Long userId) {
        return baseMapper.selectPermissionsByUserId(userId);
    }

    @Override
    public List<String> getUserRoles(Long userId) {
        return baseMapper.selectRolesByUserId(userId);
    }

    @Override
    public boolean updateUserLoginInfo(SysUser user) {
        return baseMapper.updateUserLoginInfo(user) > 0;
    }

    @Override
    public boolean verifyPassword(SysUser user, String password) {
        // 检查密码长度来判断加密方式
        // MD5: 32位十六进制字符
        // SHA-256 Base64: 通常44位字符，包含+/=等字符
        if (user.getPassword().length() == 32 && user.getPassword().matches("[a-f0-9]+")) {
            // 旧的MD5方式
            String encryptedPassword = PasswordUtils.md5Encrypt(password);
            return encryptedPassword.equals(user.getPassword());
        } else {
            // 新的SHA-256 + 用户名盐值方式
            return PasswordUtils.verifyPasswordWithUserSalt(password, user.getUserName(), user.getPassword());
        }
    }

    @Override
    public SysUser encryptPassword(String password) {
        // 注意：这个方法需要用户名才能生成正确的密码
        // 建议使用 encryptPasswordForUser(String password, String userName) 方法
        throw new UnsupportedOperationException("请使用 encryptPasswordForUser(password, userName) 方法");
    }

    /**
     * 为指定用户加密密码
     * @param password 原始密码
     * @param userName 用户名
     * @return 只包含加密密码的用户对象
     */
    public SysUser encryptPasswordForUser(String password, String userName) {
        // 使用SHA-256 + 用户名盐值加密密码
        String encryptedPassword = PasswordUtils.sha256EncryptWithUserSalt(password, userName);

        // 创建用户对象（只包含密码信息）
        SysUser user = new SysUser();
        user.setPassword(encryptedPassword);
        return user;
    }

    @Override
    public boolean changePassword(Long userId, String newPassword) {
        try {
            // 先获取用户信息，需要用户名来生成盐值
            SysUser existingUser = getById(userId);
            if (existingUser == null) {
                return false;
            }

            // 使用用户名加密新密码
            String encryptedPassword = PasswordUtils.sha256EncryptWithUserSalt(newPassword, existingUser.getUserName());

            // 更新用户密码
            SysUser user = new SysUser();
            user.setUserId(userId);
            user.setPassword(encryptedPassword);
            user.setUpdateTime(LocalDateTime.now());

            return updateById(user);
        } catch (Exception e) {
            return false;
        }
    }

    // ==================== 用户管理功能实现 ====================

    @Override
    public PageResult<UserResponse> getUserPage(UserQueryRequest queryRequest) {
        try {
            // 创建分页对象
            Page<SysUser> page = new Page<>(queryRequest.getCurrent(), queryRequest.getSize());

            // 查询分页数据
            IPage<SysUser> userPage = baseMapper.selectUserPageWithRoles(page, queryRequest);

            // 转换为响应DTO
            List<UserResponse> userResponses = userPage.getRecords().stream()
                    .map(this::convertToUserResponse)
                    .collect(Collectors.toList());

            return PageResult.of(userResponses, userPage.getTotal(), userPage.getCurrent(), userPage.getSize());
        } catch (Exception e) {
            throw new RuntimeException("查询用户分页数据失败", e);
        }
    }

    @Override
    public UserResponse getUserDetail(Long userId) {
        try {
            SysUser user = baseMapper.selectUserDetailWithRoles(userId);
            if (user == null) {
                return null;
            }
            return convertToUserResponse(user);
        } catch (Exception e) {
            throw new RuntimeException("查询用户详情失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createUser(UserCreateRequest createRequest) {
        try {
            // 检查用户名是否存在
            if (isUserNameExists(createRequest.getUserName(), null)) {
                throw new RuntimeException("用户名已存在");
            }

            // 检查邮箱是否存在
            if (StringUtils.hasText(createRequest.getEmail()) &&
                isEmailExists(createRequest.getEmail(), null)) {
                throw new RuntimeException("邮箱已存在");
            }

            // 检查手机号是否存在
            if (StringUtils.hasText(createRequest.getPhonenumber()) &&
                isPhonenumberExists(createRequest.getPhonenumber(), null)) {
                throw new RuntimeException("手机号已存在");
            }

            // 创建用户对象
            SysUser user = new SysUser();
            BeanUtils.copyProperties(createRequest, user);

            // 加密密码
            String encryptedPassword = PasswordUtils.sha256EncryptWithUserSalt(
                createRequest.getPassword(), createRequest.getUserName());
            user.setPassword(encryptedPassword);

            user.setCreateTime(LocalDateTime.now());
            user.setUpdateTime(LocalDateTime.now());

            // 保存用户
            boolean saveResult = save(user);
            if (!saveResult) {
                throw new RuntimeException("保存用户失败");
            }

            // 分配角色
            if (createRequest.getRoleIds() != null && !createRequest.getRoleIds().isEmpty()) {
                sysUserRoleService.assignRolesToUser(user.getUserId(), createRequest.getRoleIds());
            }

            return true;
        } catch (Exception e) {
            throw new RuntimeException("创建用户失败：" + e.getMessage(), e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateUser(UserUpdateRequest updateRequest) {
        try {
            // 检查用户是否存在
            SysUser existingUser = getById(updateRequest.getUserId());
            if (existingUser == null) {
                throw new RuntimeException("用户不存在");
            }

            // 检查邮箱是否存在
            if (StringUtils.hasText(updateRequest.getEmail()) &&
                isEmailExists(updateRequest.getEmail(), updateRequest.getUserId())) {
                throw new RuntimeException("邮箱已存在");
            }

            // 检查手机号是否存在
            if (StringUtils.hasText(updateRequest.getPhonenumber()) &&
                isPhonenumberExists(updateRequest.getPhonenumber(), updateRequest.getUserId())) {
                throw new RuntimeException("手机号已存在");
            }

            // 更新用户信息
            SysUser user = new SysUser();
            BeanUtils.copyProperties(updateRequest, user);
            user.setUpdateTime(LocalDateTime.now());

            boolean updateResult = updateById(user);
            if (!updateResult) {
                throw new RuntimeException("更新用户失败");
            }

            // 更新角色分配
            if (updateRequest.getRoleIds() != null) {
                sysUserRoleService.assignRolesToUser(updateRequest.getUserId(), updateRequest.getRoleIds());
            }

            return true;
        } catch (Exception e) {
            throw new RuntimeException("更新用户失败：" + e.getMessage(), e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteUser(Long userId) {
        try {
            // 检查用户是否存在
            SysUser user = getById(userId);
            if (user == null) {
                return false;
            }

            // 删除用户角色关联
            sysUserRoleService.removeAllRolesFromUser(userId);

            // 删除用户
            return removeById(userId);
        } catch (Exception e) {
            throw new RuntimeException("删除用户失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteUsers(List<Long> userIds) {
        try {
            if (userIds == null || userIds.isEmpty()) {
                return true;
            }

            // 批量删除用户角色关联
            sysUserRoleService.removeRolesByUserIds(userIds);

            // 批量删除用户
            return baseMapper.deleteBatchByIds(userIds) > 0;
        } catch (Exception e) {
            throw new RuntimeException("批量删除用户失败", e);
        }
    }

    @Override
    public boolean resetPassword(UserPasswordChangeRequest passwordChangeRequest) {
        try {
            // 验证密码是否一致
            if (!passwordChangeRequest.isPasswordMatch()) {
                throw new RuntimeException("两次输入的密码不一致");
            }

            return changePassword(passwordChangeRequest.getUserId(), passwordChangeRequest.getNewPassword());
        } catch (Exception e) {
            throw new RuntimeException("重置密码失败：" + e.getMessage(), e);
        }
    }

    @Override
    public boolean updateUserStatus(Long userId, Integer status, String updateBy) {
        try {
            return baseMapper.updateUserStatus(userId, status, updateBy) > 0;
        } catch (Exception e) {
            throw new RuntimeException("更新用户状态失败", e);
        }
    }

    @Override
    public boolean isUserNameExists(String userName, Long excludeUserId) {
        return baseMapper.countByUserName(userName, excludeUserId) > 0;
    }

    @Override
    public boolean isEmailExists(String email, Long excludeUserId) {
        if (!StringUtils.hasText(email)) {
            return false;
        }
        return baseMapper.countByEmail(email, excludeUserId) > 0;
    }

    @Override
    public boolean isPhonenumberExists(String phonenumber, Long excludeUserId) {
        if (!StringUtils.hasText(phonenumber)) {
            return false;
        }
        return baseMapper.countByPhonenumber(phonenumber, excludeUserId) > 0;
    }

    /**
     * 转换用户实体为响应DTO
     */
    private UserResponse convertToUserResponse(SysUser user) {
        UserResponse response = new UserResponse();
        BeanUtils.copyProperties(user, response);

        // 设置角色信息
        if (user.getRoles() != null) {
            response.setRoles(user.getRoles());
        }

        return response;
    }
}
